using Microsoft.AspNetCore.SignalR;
using Microsoft.AspNetCore.Authorization;
using ChatBackend.Services;
using ChatBackend.DTOs;
using System.Security.Claims;

namespace ChatBackend.Hubs
{
    [Authorize]
    public class ChatHub : Hub
    {
        private readonly IChatService _chatService;
        private readonly IAuthService _authService;
        private static readonly Dictionary<string, int> _connectionUserMap = new();
        private static readonly Dictionary<int, HashSet<string>> _userConnections = new();

        public ChatHub(IChatService chatService, IAuthService authService)
        {
            _chatService = chatService;
            _authService = authService;
        }

        public override async Task OnConnectedAsync()
        {
            try
            {
                var userId = GetUserId();
                if (userId.HasValue)
                {
                    // 记录连接
                    _connectionUserMap[Context.ConnectionId] = userId.Value;

                    if (!_userConnections.ContainsKey(userId.Value))
                    {
                        _userConnections[userId.Value] = new HashSet<string>();
                    }
                    _userConnections[userId.Value].Add(Context.ConnectionId);

                    // 更新用户在线状态
                    await _authService.UpdateUserOnlineStatusAsync(userId.Value, true);

                    // 加入用户的所有聊天室组
                    try
                    {
                        var chatRooms = await _chatService.GetUserChatRoomsAsync(userId.Value);
                        foreach (var chatRoom in chatRooms)
                        {
                            await Groups.AddToGroupAsync(Context.ConnectionId, $"ChatRoom_{chatRoom.Id}");
                        }
                    }
                    catch (Exception ex)
                    {
                        // 记录错误但不阻止连接
                        Console.WriteLine($"加入聊天室组时出错: {ex.Message}");
                    }

                    // 通知其他用户该用户上线
                    await Clients.Others.SendAsync("UserOnline", userId.Value);
                }

                await base.OnConnectedAsync();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"SignalR连接时出错: {ex.Message}");
                await Clients.Caller.SendAsync("Error", "连接失败");
                throw;
            }
        }

        public override async Task OnDisconnectedAsync(Exception? exception)
        {
            if (_connectionUserMap.TryGetValue(Context.ConnectionId, out var userId))
            {
                _connectionUserMap.Remove(Context.ConnectionId);
                
                if (_userConnections.ContainsKey(userId))
                {
                    _userConnections[userId].Remove(Context.ConnectionId);
                    
                    // 如果用户没有其他连接，则设置为离线
                    if (_userConnections[userId].Count == 0)
                    {
                        _userConnections.Remove(userId);
                        await _authService.UpdateUserOnlineStatusAsync(userId, false);
                        
                        // 通知其他用户该用户离线
                        await Clients.Others.SendAsync("UserOffline", userId);
                    }
                }
            }

            await base.OnDisconnectedAsync(exception);
        }

        public async Task SendMessage(SendMessageDto sendMessageDto)
        {
            var userId = GetUserId();
            if (!userId.HasValue) return;

            try
            {
                var message = await _chatService.SendMessageAsync(userId.Value, sendMessageDto);
                
                // 发送消息到聊天室组
                await Clients.Group($"ChatRoom_{sendMessageDto.ChatRoomId}")
                    .SendAsync("ReceiveMessage", message);
            }
            catch (Exception ex)
            {
                await Clients.Caller.SendAsync("Error", ex.Message);
            }
        }

        public async Task JoinChatRoom(int chatRoomId)
        {
            var userId = GetUserId();
            if (!userId.HasValue) return;

            try
            {
                var success = await _chatService.JoinChatRoomAsync(chatRoomId, userId.Value);
                if (success)
                {
                    await Groups.AddToGroupAsync(Context.ConnectionId, $"ChatRoom_{chatRoomId}");
                    await Clients.Caller.SendAsync("JoinedChatRoom", chatRoomId);
                    
                    // 通知聊天室其他成员
                    await Clients.OthersInGroup($"ChatRoom_{chatRoomId}")
                        .SendAsync("UserJoinedChatRoom", chatRoomId, userId.Value);
                }
                else
                {
                    await Clients.Caller.SendAsync("Error", "无法加入聊天室");
                }
            }
            catch (Exception ex)
            {
                await Clients.Caller.SendAsync("Error", ex.Message);
            }
        }

        public async Task LeaveChatRoom(int chatRoomId)
        {
            var userId = GetUserId();
            if (!userId.HasValue) return;

            try
            {
                var success = await _chatService.LeaveChatRoomAsync(chatRoomId, userId.Value);
                if (success)
                {
                    await Groups.RemoveFromGroupAsync(Context.ConnectionId, $"ChatRoom_{chatRoomId}");
                    await Clients.Caller.SendAsync("LeftChatRoom", chatRoomId);
                    
                    // 通知聊天室其他成员
                    await Clients.OthersInGroup($"ChatRoom_{chatRoomId}")
                        .SendAsync("UserLeftChatRoom", chatRoomId, userId.Value);
                }
            }
            catch (Exception ex)
            {
                await Clients.Caller.SendAsync("Error", ex.Message);
            }
        }

        public async Task MarkAsRead(int chatRoomId)
        {
            var userId = GetUserId();
            if (!userId.HasValue)
            {
                Console.WriteLine($"MarkAsRead: 用户ID为空");
                return;
            }

            try
            {
                Console.WriteLine($"MarkAsRead: 开始标记聊天室 {chatRoomId} 为已读，用户ID: {userId.Value}");
                await _chatService.MarkAsReadAsync(chatRoomId, userId.Value);
                Console.WriteLine($"MarkAsRead: 成功标记聊天室 {chatRoomId} 为已读");
                await Clients.Caller.SendAsync("MarkedAsRead", chatRoomId);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"MarkAsRead: 标记已读失败 - {ex.Message}");
                await Clients.Caller.SendAsync("Error", ex.Message);
            }
        }

        public async Task StartTyping(int chatRoomId)
        {
            var userId = GetUserId();
            if (!userId.HasValue) return;

            await Clients.OthersInGroup($"ChatRoom_{chatRoomId}")
                .SendAsync("UserStartedTyping", chatRoomId, userId.Value);
        }

        public async Task StopTyping(int chatRoomId)
        {
            var userId = GetUserId();
            if (!userId.HasValue) return;

            await Clients.OthersInGroup($"ChatRoom_{chatRoomId}")
                .SendAsync("UserStoppedTyping", chatRoomId, userId.Value);
        }

        public async Task DeleteMessage(int messageId)
        {
            var userId = GetUserId();
            if (!userId.HasValue) return;

            try
            {
                var success = await _chatService.DeleteMessageAsync(messageId, userId.Value);
                if (success)
                {
                    // 这里需要获取消息所属的聊天室ID，简化起见，可以在客户端传递
                    await Clients.Caller.SendAsync("MessageDeleted", messageId);
                }
                else
                {
                    await Clients.Caller.SendAsync("Error", "无法删除消息");
                }
            }
            catch (Exception ex)
            {
                await Clients.Caller.SendAsync("Error", ex.Message);
            }
        }

        public async Task EditMessage(int messageId, string newContent)
        {
            var userId = GetUserId();
            if (!userId.HasValue) return;

            try
            {
                var editedMessage = await _chatService.EditMessageAsync(messageId, userId.Value, newContent);
                if (editedMessage != null)
                {
                    // 通知聊天室所有成员消息已编辑
                    await Clients.Group($"ChatRoom_{editedMessage.ChatRoomId}")
                        .SendAsync("MessageEdited", editedMessage);
                }
                else
                {
                    await Clients.Caller.SendAsync("Error", "无法编辑消息");
                }
            }
            catch (Exception ex)
            {
                await Clients.Caller.SendAsync("Error", ex.Message);
            }
        }

        private int? GetUserId()
        {
            var userIdClaim = Context.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
            return int.TryParse(userIdClaim, out var userId) ? userId : null;
        }

        public static bool IsUserOnline(int userId)
        {
            return _userConnections.ContainsKey(userId) && _userConnections[userId].Count > 0;
        }

        public static List<string> GetUserConnections(int userId)
        {
            return _userConnections.ContainsKey(userId) ? _userConnections[userId].ToList() : new List<string>();
        }
    }
}
